import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:model_api_test/generated/assets.dart';
import 'package:model_api_test/provider/MyApi.dart';
import 'package:model_api_test/util/audio_decode_io.dart'
    if (dart.library.html) 'package:model_api_test/util/audio_decode_web.dart';

import 'state.dart';

class HomeLogic extends GetxController {
  final HomeState state = HomeState();

  final segmentIndexInput = ''.obs;

  int _segmentIndex = 0;

  Future<void> transcribeFromAssetWavPureDart() async {
    try {
      state.statusMessage.value = '加载 mp3.mp3 并解码为 PCM...';
      final data = await rootBundle.load(Assets.assetsMp3);
      final mp3Bytes = data.buffer.asUint8List();

      // 使用平台合适的方式解码 MP3（Web: WebAudio；Android/iOS: FFmpeg）
      final decoded = await decodeMp3Bytes(mp3Bytes);

      // 重采样到 16kHz（线性插值），与 test.py 一致
      const targetRate = 16000;
      final resampled = _resampleLinearF32(
        decoded.samples,
        decoded.sampleRate,
        targetRate,
      );
      // 转为小端 float32 字节并 Base64
      final outBytes = Uint8List.view(resampled.buffer);
      final audioBase64 = base64Encode(outBytes);

      final index = int.tryParse(segmentIndexInput.value) ?? _segmentIndex;
      final resp = await MyApi.instance.transcribeSegment(
        segmentIndex: index,
        audioBase64: audioBase64,
      );
      if (resp != null) {
        state.statusMessage.value = jsonEncode(resp);
        _segmentIndex = index + 1;
      }
    } catch (e) {
      state.statusMessage.value = '$e';
    }
  }

  Future<void> checkService() async {
    state.statusMessage.value = '检查服务中...';
    state.statusMessage.value = await MyApi.instance.getStatus() ?? '';
  }

  /// 线性插值重采样（float32），支持任意采样率到目标采样率
  Float32List _resampleLinearF32(Float32List input, int srcRate, int dstRate) {
    if (srcRate == dstRate) return input;
    final outLen = ((input.length * dstRate) / srcRate).floor();
    final out = Float32List(outLen);
    final ratio = srcRate / dstRate;
    for (int i = 0; i < outLen; i++) {
      final pos = i * ratio;
      final idx = pos.floor();
      final frac = pos - idx;
      final s0 = input[idx];
      final s1 = input[idx < input.length - 1 ? idx + 1 : idx];
      out[i] = s0 + (s1 - s0) * frac;
    }
    return out;
  }
}
